/* CPP Assignemnt 3 (COSC1152-2011-S2)
 * Elliott O'Dea-Joyce s3074110@student.rmit.edu.au
 * Ross Nye s9455459@student.rmit.edu.au
 */

#include "graph_strat.h"
#include "fact.h"
#include "utils.h"
#include <iostream>

// just prints the usage details for the program
void print_usage()
{
	std::cout << "Generates a MST graph" << std::endl << "Usage:" << std::endl;
	std::cout << "\tass3 <filename> <graph_type> <algorithm>" << std::endl;
	std::cout << "\tass3 -g:<num vertex> <graph type> <algorithm>" << std::endl;
	std::cout << "Where:" << std::endl;

	std::cout << "\t<filename>    filename for graph file" << std::endl;
	std::cout << "\t<num vertex>  number of vertex in graph created" << std::endl;

	std::cout << "\t<graph type>  0 for complete graph" << std::endl;
	std::cout << "\t              1 for delaunay triangle" << std::endl;
	std::cout << "\t<algotithm>   0 for Kruskals" << std::endl;
	std::cout << "\t              1 for Prims" << std::endl;

	std::cout << std::endl << "\talgorithm = 0 for kruskals, 1 for prims\n";
};

// method just used to neaten up main. It greats the correct MakeGraph to use
MakeGraph* createGraphStrategy(int graph_type)
{
	if (graph_type == 0)
	{
#if DEBUG
		std::cout << "Using Complete Graph" << std::endl;
#endif
		return new MakeGraph(new CompleteGraph());
	}
	else if (graph_type == 1)
	{
#if DEBUG
		std::cout << "Using delaunay triangle" << std::endl;
#endif
		return new MakeGraph(new DelaunayGraph());
	}
	else
	{
		std::cout << "Graph type error:" << std::endl;
		print_usage();
		exit(EXIT_SUCCESS);
	}
	return NULL; // stops warnings
}




int main(int argc, char **argv)
{
	try
		{
		if (argc != 4)
		{
			print_usage();
			return EXIT_SUCCESS;
		}
		
		int graph_type = toInt(argv[2]);
		int algo_type = toInt(argv[3]);
	
		// create graph stategy, load points, create vertices, edges and weights
		MakeGraph* mg = createGraphStrategy(graph_type);
		mg->create(argv[1]);
		
		GraphFactory* gf = GraphFactory::create(algo_type);
				
		// begin timer then use factory with strategy to generate the mst
		beginTimer();
		
		gf->generateMST(mg);
		
		// end the timer and output the computation time
		// endTimer();  // moved to inside the algos prior to writing file
		float time = getTime();
		std::cout << "MST computation time: " << time << "ms\n";
		
		// write test date to file
		std::ofstream fout;
		fout.open("testdata.csv",std::ios::app);
		if (!fout.is_open())
			throw std::runtime_error("Unable to open data file");
		
		fout << graph_type << "," << algo_type << "," << mg->getNumVertex() << ",";
		fout << time << "," << argv[1] << "," << gf->getAlgoName() << ",";
		fout << mg->getStratName() << std::endl;
		fout.close();
		
		delete mg;
		delete gf;
	}
	catch(std::runtime_error e)
	{
		std::cerr << e.what() << std::endl;
	}
	return EXIT_SUCCESS;
}

